package
{
	import com.*;
	import events.GCCityEvent;
	import events.GCEvent;
	import flash.events.Event;
	import ui.CitySprite;
	import data.*;
	import menu.*;

	import flash.display.Sprite;
	import org.flixel.*;
	
	public class GCMainDisplay extends Sprite
	{
		public static const AT_CITY_MENU:uint = 0;
		public static const AT_WORLD_MAP:uint = 1;
		public static const AT_SHIP_REPAIR:uint = 2;
		public static const AT_WORKER_ASSIGN:uint = 3;
		public static const AT_BUILD_POST:uint = 4;
		public static const AT_INVENTORY:uint = 5;
		public static const AT_SYNTHESIZE:uint = 6;
		public static const AT_WAREHOUSE:uint = 7;
		public static const AT_CITY_MARKET:uint = 8;
		public static const AT_TROPHY_ROOM:uint = 9;
		
		/*
		 * All menus can reference main display width
		 * and height.
		 */
		public static var WIDTH:int;
		public static var HEIGHT:int;
		 
		/*
		Reference to all possible menus that will appear in the
		main display of our game
		*/
		private var _cityMenu:GCCityMenu;
		private var _marketMenu:GCMarketMenu;
		private var _inventoryMenu:GCInventoryMenu;
		private var _synthesizeMenu:GCSynthesizeMenu;
		private var _shipRepairMenu:GCShipRepairMenu;
		private var _buildPostMenu:GCTradePostMenu;
		private var _workerAssignMenu:GCWorkerAssignMenu;
		private var _cityWarehouseMenu:GCWarehouseMenu;
		private var _worldMap:GCWorldMapDisplay;
		private var _trophyRoom:GCTrophyRoom;
		
		/*
		Variable to keep track of which item we have currently
		displayed in this component.
		*/
		private var _currentState:int;
		private var _currentMenu:GCSuperMenu;
		private var _currentCity:GCCity;
		private var _isAtCity:Boolean;
		
		public function GCMainDisplay(width:int, height:int, x:int = 0, y:int = 0)
		{
			super();
			this.x = x;
			this.y = y;
			WIDTH = width;
			HEIGHT = height;
			
			_cityMenu = new GCCityMenu();
			_marketMenu = new GCMarketMenu();
			_inventoryMenu = new GCInventoryMenu();
			_synthesizeMenu = new GCSynthesizeMenu();
			_shipRepairMenu = new GCShipRepairMenu();
			_buildPostMenu = new GCTradePostMenu();
			_workerAssignMenu = new GCWorkerAssignMenu();
			_cityWarehouseMenu = new GCWarehouseMenu();
			_worldMap = new GCWorldMapDisplay();
			_trophyRoom = new GCTrophyRoom();
			
			/*
			 * Initialize the display to show the world map at first.
			 * Current city is initialized based on saved player data from
			 * their last play session.
			 */
			_currentState = -1;
			_currentCity = GCPlayState.getCurrentCity();
			_isAtCity = false;
			
			init();

			this.graphics.beginFill(0xFFFFFF);
			this.graphics.drawRect(0, 0, width, height);
			this.graphics.endFill();
		}
		
		/**
		 * Function to explicitly change to a new state.
		 * 
		 * (Important note: As it stands now we can never 'exit' a city menu nor the
		 * world map menu so either of these two should always be on the display at all times)
		 * 
		 * @param	newState
		 */
		public function changeState(newState:uint):void
		{
			//trace(newState + " " + _currentState);
			
			// Don't need to change, if we are already at the new state!
			if (_currentState == newState)
			{
				return;
			}
			
			/*
			 * Clean up old menus
			 */
			switch (_currentState)
			{
				case AT_INVENTORY:
					_inventoryMenu.closeMenu();
					removeChild(_inventoryMenu);
					break;
				case AT_SHIP_REPAIR:
					_shipRepairMenu.closeMenu();
					removeChild(_shipRepairMenu);
					break;
				case AT_SYNTHESIZE:
					_synthesizeMenu.closeMenu();
					removeChild(_synthesizeMenu);
					break;
				case AT_WORLD_MAP:
					_worldMap.cleanMenu();
					removeChild(_worldMap);
					break;
				case AT_WAREHOUSE:
					_cityWarehouseMenu.closeMenu();
					removeChild(_cityWarehouseMenu);
					break;
				case AT_WORKER_ASSIGN:
					_workerAssignMenu.closeMenu();
					removeChild(_workerAssignMenu);
					break;
				case AT_BUILD_POST:
					_buildPostMenu.closeMenu();
					removeChild(_buildPostMenu);
					break;
				case AT_CITY_MARKET:
					_marketMenu.closeMenu();
					removeChild(_marketMenu);
					break;
				case AT_CITY_MENU:
					_cityMenu.closeMenu();
					removeChild(_cityMenu);
					break;
				case AT_TROPHY_ROOM:
					break;
			}

			_currentState = newState;
			/*
			 * Go to a new state, add new menus to display
			 */
			switch (newState)
			{
				case AT_INVENTORY:
					_inventoryMenu.openMenu(GCPlayState.getPlayerInventory());
					addChild(_inventoryMenu);
					_currentMenu = _inventoryMenu;
					break;
				case AT_SHIP_REPAIR:
					_shipRepairMenu.openMenu(GCPlayState.getCurrentShip());
					addChild(_shipRepairMenu);
					_currentMenu = _shipRepairMenu;
					break;
				case AT_SYNTHESIZE:
					_synthesizeMenu.openMenu(GCPlayState.getPlayerInventory());
					addChild(_synthesizeMenu);
					_currentMenu = _synthesizeMenu;
					break;
				case AT_WORLD_MAP:
					_isAtCity = false;
					_worldMap.openMenu();
					addChild(_worldMap);
					_currentMenu = _worldMap;
					break;
				case AT_WAREHOUSE:
					addChild(_cityWarehouseMenu);
					_currentMenu = _cityWarehouseMenu;
					break;
				case AT_WORKER_ASSIGN:
					addChild(_workerAssignMenu);
					_currentMenu = _workerAssignMenu;
					break;
				case AT_BUILD_POST:
					addChild(_buildPostMenu);
					_currentMenu = _buildPostMenu;
					break;
				case AT_CITY_MARKET:
					addChild(_marketMenu);
					_currentMenu = _marketMenu;
					break;
				case AT_CITY_MENU:
					_isAtCity = true;
					_cityMenu.openMenu(_currentCity);
					addChild(_cityMenu);
					_currentMenu = _cityMenu;
					break;
				case AT_TROPHY_ROOM:
					addChild(_trophyRoom);
					_currentMenu = _trophyRoom;
					break;
			}
		}
		
		public function refreshDisplay(event:Event = null):void
		{
			_currentMenu.refresh();
		}
		
		public function enableScrolling():void
		{
			if(_currentMenu != null)
				_currentMenu.enableScrolling();
		}
		
		public function disableScrolling():void
		{
			if(_currentMenu != null)
				_currentMenu.disableScrolling();
		}
		
		private function init():void
		{
			/*
			Moving to a new screen from the city menu. 
			*/
			_cityMenu.addEventListener(GCEvent.GO_TO_MARKET_EVENT, onGotoMarket);
			_cityMenu.addEventListener(GCEvent.GO_TO_WAREHOUSE_EVENT, onGotoWarehouse);
			_cityMenu.addEventListener(GCEvent.GO_TO_BUILD_POST_EVENT, onBuildPost);
			_cityMenu.addEventListener(GCEvent.GO_TO_ASSIGN_JOB_EVENT, onGotoJobs);
			
			_marketMenu.addEventListener(GCEvent.EXIT_MENU_EVENT, onExitMarket);
			_cityWarehouseMenu.addEventListener(GCEvent.EXIT_MENU_EVENT, onExitWarehouse);
			_buildPostMenu.addEventListener(GCEvent.EXIT_MENU_EVENT, onExitPost);
			_workerAssignMenu.addEventListener(GCEvent.CONFIRM_MENU_EVENT, onConfirmWorkers);
			_workerAssignMenu.addEventListener(GCEvent.CANCEL_MENU_EVENT, onCancelWorkers);
			
			_inventoryMenu.addEventListener(GCEvent.EXIT_MENU_EVENT, onExitInventory);
			_synthesizeMenu.addEventListener(GCEvent.EXIT_MENU_EVENT, onExitSynthesize);
			_shipRepairMenu.addEventListener(GCEvent.EXIT_MENU_EVENT, onExitShipMenu);
			
			_worldMap.addEventListener(GCEvent.GO_TO_CITY_EVENT, onGoToCity);
			_worldMap.addEventListener(GCEvent.CHANGE_CITY_EVENT, onChangeCity);
			_worldMap.addEventListener(GCEvent.VIEW_WAREHOUSE_REMOTELY_EVENT, onViewWarehouseRemotely);
			
		}
		
		private function onGotoMarket(event:GCEvent):void
		{
			_marketMenu.openMenu(GCPlayState.getPlayerInventory(), 
								GCPlayState.getCurrentCity()._warehouse, 
								GCPlayState.getCurrentCity()._playerSales, 
								GCPlayState.getCurrentCity().getId());
			changeState(AT_CITY_MARKET);
		}
		
		private function onGotoWarehouse(event:GCEvent):void
		{
			_cityWarehouseMenu.openMenu(GCPlayState.getPlayerInventory(), 
										GCPlayState.getCurrentCity()._warehouse, 
										GCPlayState.getCurrentCity()._playerSales, 
										GCPlayState.getCurrentCity().getId());
			changeState(AT_WAREHOUSE);
		}
		
		private function onBuildPost(event:GCEvent):void
		{
			_buildPostMenu.openMenu(_currentCity.getAllPossibleBuildings(), _currentCity.getAllAlreadyConstructed());
			changeState(AT_BUILD_POST);
		}
		
		private function onGotoJobs(event:GCEvent):void
		{
			_workerAssignMenu.openMenu(_currentCity.getConstructedBuildings(), _currentCity.totalWorkers, GCPlayState.getWorkersOnShip());
			changeState(AT_WORKER_ASSIGN);
		}
		
		private function onExitMarket(event:GCEvent):void
		{
			trace("exit market");
			goBackToOld();
		}
		
		private function onExitWarehouse(event:GCEvent):void
		{
			goBackToOld();
		}
		
		private function onExitInventory(event:GCEvent):void
		{
			
			goBackToOld();
		}
		
		private function onExitPost(event:GCEvent):void
		{
			goBackToOld();
		}
				
		private function onExitSynthesize(event:GCEvent):void
		{
			
			goBackToOld();
		}
		
		private function onExitShipMenu(event:GCEvent):void
		{
			goBackToOld();
		}
		
		private function onConfirmWorkers(event:GCEvent):void
		{
			goBackToOld();
		}
		
		private function onCancelWorkers(event:GCEvent):void
		{
			goBackToOld();
		}

		private function goBackToOld():void
		{
			if (_isAtCity)
			{
				changeState(AT_CITY_MENU);
			}
			else
			{
				changeState(AT_WORLD_MAP);
			}
		}
		
		private function onGoToCity(event:GCCityEvent):void
		{
			var city:GCCity = GCPlayState.getCityData(event.city);
			if (city != null)
			{				
				//_currentCity = city;
				
				changeState(AT_CITY_MENU);
			}
			else
			{
				trace("ERROR: The city you are trying to enter is somehow null!");
			}
		}
		
		/**
		 * Function that is triggered when the player their location from
		 * one city to another. Occurs when the user sails to another location
		 * via the map.
		 * 
		 * @param	event
		 */
		private function onChangeCity(event:GCCityEvent):void
		{
			var city:GCCity = GCPlayState.getCityData(event.city);
			if (city != null)
			{				
				trace("Successfully reached the city " + city.getName());
				_currentCity = city;
				GCPlayState.setNewPlayerLocation(city.getId());
			}
			else
			{
				trace("ERROR: The city you are trying to sail to!");
			}
		}
		
		private function onViewWarehouseRemotely(event:GCCityEvent):void
		{
			var cityInventory:GCInventory = GCPlayState.getCityData(event.cityId).getInventoryFromCity();
			var citySalesInventory:GCInventory = GCPlayState.getCityData(event.cityId)._playerSales;
			_cityWarehouseMenu.openMenu(GCPlayState.getPlayerInventory(), cityInventory, citySalesInventory, event.cityId);
			changeState(AT_WAREHOUSE);
		}
	}
}